package servlet.other;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static java.lang.System.out;

//上传文件的Servlet类
@WebServlet(name = "UploadServlet", urlPatterns = "/wk07/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    //这边他会去找out目录
    private final static String FILE_SAVE_PREFIX = "upload\\";


    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {


        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=UTF-8");
        //获取用户Id和文件权限,创建当前时间即上传时间(datetime对应util的date)
        int power = 0;
        int userId = Integer.parseInt(request.getSession().getAttribute("userId").toString());
        Date date = new Date();
        //获取字符流
        PrintWriter writer = response.getWriter();

        //文件的路径和名字,先放到外部作为全局变量,方便随时取值
        String filePath = "";
        String fileName = "";

        //这段代码的作用是检查当前的 HTTP 请求是否包含了文件上传的内容，如果是多部分请求
        // 则返回 true，否则返回 false
        try {
            // 创建DiskFileItemFactory工厂对象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 创建 ServletFileUpload对象
            ServletFileUpload fileupload = new ServletFileUpload(factory);
            //设置字符编码
            fileupload.setHeaderEncoding("utf-8");

            //设置文件缓存目录，如果该目录不存在则新创建一个
            File f = new File(FILE_SAVE_PREFIX);
            if (!f.exists()) {
                f.mkdirs();
            }
            // 设置文件的缓存路径
            factory.setRepository(f);


            // 解析 request，得到上传文件的FileItem对象
            //TODO:使用 fileupload.parseRequest(request);就不可以使用 request.getParameter();否则获取不到任何数据
            List<FileItem> fileitems = fileupload.parseRequest(request);
            // 遍历集合
            for (FileItem fileitem : fileitems) {
                {
                    // 判断是否为普通字段;是的话就是文件权限字段
                    if (fileitem.isFormField()) {
                        String s = fileitem.getFieldName();
                        out.println(s);
                        String value = fileitem.getString("utf-8");
                        out.println(value);
                        //还真能获取到filePwer的值,现在根据这个值来改变power
                        power = Integer.parseInt(value);
                    } else {
                        // 获取上传的文件名
                        String filename = fileitem.getName();
                        //处理上传文件
                        if (filename != null && !filename.equals("")) {
                            writer.print("上传的文件名称是：" + filename + "<br />");
                            fileName = filename;
                            // 截取出文件名
                            filename = filename.substring(filename.lastIndexOf("\\") + 1);
                            // 文件名需要唯一
                            filename = UUID.randomUUID() + "_" + filename;
                            filePath = "/upload/" + filename;
                            //将服务器中文件夹路径与文件名组合成完整的服务器端路径
                            //一定要找打这边服务器的路径(即使用他的getServletFContext方法 , 不然会找到tomcat的目录X:\apache-tomcat-9.0.2\bin \ upload
               /*         String filepath = getServletFContext()
                                .getRealPath(FILE_SAVE_PREFIX + filename);*/
                            //String projectPath = System.getProperty("user.dir");  获取项目目录
                            //当前上传路径:out/artifacts/Web_App_war_exploded/upload
                            String filepath = getServletContext()
                                    .getRealPath(FILE_SAVE_PREFIX + filename);
                            // 创建文件
                            File file = new File(filepath);
                            file.getParentFile().mkdirs();
                            file.createNewFile();
                            // 获得上传文件流
                            InputStream in = fileitem.getInputStream();
                            // 使用FileOutputStream打开服务器端的上传文件
                            FileOutputStream out = new FileOutputStream(file);
                            // 流的拷贝
                            byte[] buffer = new byte[1024];//每次读取1个字节
                            int len;
                            //开始读取上传文件的字节，并将其输出到服务端的上传文件输出流中
                            while ((len = in.read(buffer)) > 0)
                                out.write(buffer, 0, len);
                            // 关闭流
                            in.close();
                            out.close();
                            // 删除临时文件
                            fileitem.delete();
                            writer.print("上传文件成功！<br />");
                        }
                    }
                }
            }

            //数据库操作
            if (!fileName.equals("")) {
                Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai", "root", "123456");
                QueryRunner queryRunner = new QueryRunner();
                //AI编写
                String sql = "INSERT INTO file (file_path, file_name, user_id, power, up_time) VALUES ('"
                        + filePath + "', '" + fileName + "', '" + userId + "', '" + power + "', '" + new java.sql.Timestamp(date.getTime()) + "')";
                //有insert方法可以使用，只不过没有使用
                queryRunner.update(connection, sql);
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        //能进入这个上传界面,必然是用户权限
        writer.println("<a href=\"fileSystem.jsp?power=" + 1 + "\">返回上一页</a>\n");
    }


    //注意:post和get请求上传文件有所不同,post请去适合接收单一的文件不包含字段
    // 网上查阅：文件上传最好还是用post请求
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
